#include <iostream>
#include <gtk/gtk.h>
#include "variables_data.h"
using namespace std;

extern GtkBuilder *builder;

//Ridichiarazione con parola chiave extern delle variabili globali usate nei vari file.
extern bool flag;

extern giocatori gamer, campo_gioco[6][7];

extern const char *P1, *P2;

extern unsigned int campo_gioco_pos[6][7];
extern unsigned int red_cell, yellow_cell;
extern unsigned int token;
extern unsigned int r_m_won, y_m_won; 

/**
 * Questa funzione setta la 'sensitive' delle prime 'x' caselle a 'true' o 'false' 
 * a seconda del valore attuale della variabile flag.
 * E' usata all'interno della funzione ::create_match ed anche nelle funzioni 
 * per il controllo del vincitore.
 * (Il terminatore è inserito fuori dal ciclo perchè non ha senso metterlo 42 volte).
 * 
 * @param[in] x Numero di caselle di cui settare la sensitive.
 * @param[in] flag A seconda del suo valore le celle saranno cliccabili oppure no.
 */
void set_index_sensitive(int x, bool flag)
{	
char cifre[3];
cifre[2]='\0';							
for(int i=1; i<=x; i++){		
	cifre[0]=static_cast<char>(i/10+48);
	cifre[1]=static_cast<char>(i%10+48);
	const char *pun=cifre;
	gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(builder,pun)), flag);
						}
}

/**
 * Questa funzione prepara il campo da gioco per una nuova partita.
 * Riempie la matrice ::campo_gioco_pos riga per riga da sinistra verso destra con valori
 * da 1 a 42 che corrispondono ai nomi dei bottoni;
 * nell'altra matrice invece setta tutte le celle a 'vuota'.
 * Inoltre chiama la funzione ::set_index_sensitive per rendere non cliccabili i bottoni da 1 a 35
 * cioè tutti tranne l'ultima riga di bottoni (questo vale quando parte il gioco).
 */
void inizializza_campo()
{
	int cont=0;
	
	for(int i=0; i<6; i++){
		for(int j=0; j<7; j++){
		campo_gioco_pos[i][j]=++cont;	
		D2(cout<<campo_gioco_pos[i][j]<<endl);
		campo_gioco[i][j]=vuota;								
							  }
						  }	
	D1(cout<<"inizializzazione matrice 'pos' completata "<<endl);
	set_index_sensitive(35, false);
}

/**
 * Con i cicli seguenti si controllano gli indici 'i' e 'j' che identificano
 * la cella nella quale è memorizzato il numero del bottone premuto;
 * questi li sfrutto per riempire la cella individuata dai medesimi indici
 * ma dell'altra matrice di tipo enumerato. Così posso marcare quella cella con il valore
 * 'player1' o 'player2' poi fare i vari controlli per vedere se ci sono
 * 4 caselle vicine dello stesso colore.
 * In questo modo potrò vedere quando un giocatore vince.
 * 
 * @param[in] id_bottone Contiene il numero della cella premuta dal giocatore.
 */
void set_cell_owner(unsigned int id_bottone)
{
for(int i=0; i<6; i++){
	for(int j=0; j<7; j++)
		if(campo_gioco_pos[i][j]==id_bottone){									
			campo_gioco[i][j]=gamer;
			D2(cout<<campo_gioco[i][j]<<endl);//stampa 0=giocatore rosso, 1=giocatore giallo		
			break;						
											 }							 								
					 }	
}

/**
 * Funzione di gestione turni giocatori.
 * Alterna ::gamer assegnandogli il valore opposto rispetto a quello che
 * aveva in precedenza e aggiorna la label contenente il nome del giocatore attuale. 
 */
void change_turn()
{
	if(gamer==player2){
		gamer=player1;
		GtkLabel *turn_label =GTK_LABEL(gtk_builder_get_object(builder,"label68"));
		gtk_label_set_text (turn_label, P1);
					  }

	else{
		gamer=player2;
		GtkLabel *turn_label =GTK_LABEL(gtk_builder_get_object(builder,"label68"));
		gtk_label_set_text (turn_label, P2);
		}
}

/**
 * Questa funzione prende in ingresso i punteggi dei due giocatori e la 'label'
 * associata al relativo giocatore convertendoli in 'char'.
 * Dopodichè questa stringa così ottenuta viene settata nella finestra delle
 * vittorie sotto al nome del giocatore che ha totalizzato quel punteggio. 
 * 
 * @param[in] punti Contiene una volta le vittorie totali del g1 e una volta del g2.
 * @param[in] etichetta Contiene la label che una volta si riferisce al g1 e una volta al g2.
 */
void points_conversion(unsigned int punti, const char etichetta[])
{
	char partite[3]; 
	const char *pun_matches=partite;
	partite[2]='\0';

	partite[0]=static_cast<char>((punti)/10+48); //ricavo le decine
	partite[1]=static_cast<char>((punti)%10+48); //ricavo le unità

	GtkLabel *p_label =GTK_LABEL(gtk_builder_get_object(builder, etichetta));
	gtk_label_set_text (p_label, pun_matches);
}

/**
 * Aggiorna i risultati delle partite nella finestra informativa chiamando la
 * funzione ::points_conversion due volte ma con parametri diversi a seconda
 * che si tratti del giocatore 1 o 2.
 */
void points_updater()	
{
	if(gamer==player1)	 
		points_conversion(r_m_won, "label54");
					  
	else
		points_conversion(y_m_won, "label55");	
		
}

/**
 * Funzione che crea nuova partita (dopo aver premuto 'Nuova partita' quando vince un giocatore
 * o dal menù 'File' ). Questa funzione pulisce il campo, nel senso che per ogni
 * cella ricarica l'immagine della cella blu vuota (come all'avvio del gioco);
 * inoltre setta a true la sensitive di tutte le celle.
 * Fa questo poichè all'interno della successiva funzione ::inizializza_campo 
 * la sensitive verrà settata a false per tutte le celle tranne l'ultima riga, in questo modo
 * come da regolamento si avrà a disposizione per la prima mossa solo la riga inferiore del campo.
 */
void create_match()
{
 	GtkWidget *red_dialog =GTK_WIDGET(gtk_builder_get_object(builder,"dialog3"));
	gtk_widget_hide(red_dialog) ;

	GtkWidget *yellow_dialog =GTK_WIDGET(gtk_builder_get_object(builder,"dialog4"));
	gtk_widget_hide(yellow_dialog) ; 	
	
	char word[8];
	word[0]='i', word[1]='m', word[2]='a', word[3]='g', word[4]='e', word[7]='\0';								
	for(int k=1; k<=42; k++){		
		word[5]=static_cast<char>(k/10+48); //ricavo le decine
		word[6]=static_cast<char>(k%10+48); //ricavo le unità
		const char *pun=word;
		gtk_image_set_from_file(GTK_IMAGE(gtk_builder_get_object(builder,pun)), "cella_blu.png");
							}
	token=0;
	
	set_index_sensitive(42, true);

	inizializza_campo();	
}

/**
 * Funzione che setta effettivamente i nomi dei giocatori 
 * (verranno usati per la finestra che mostra le vittorie e nella
 *  barra inferiore del campo di gioco che indica il turno attuale).
 * P1 e P2 prenderanno rispettivamente i nomi modificati del primo e del secondo giocatore
 * grazie ad un assegnamento di puntatori (visto che P1 e P2 sono globali).
 * Se viene rilevata come 'attiva' la selezione del giocatore_1 allora verrà settato il 
 * nome relativo al g1. Altrimenti verrà settato il nome relativo al g2 se attiva questa. 
 *
 * @param[in] player_name Puntatore costante alla stringa contenente il nome appena inserito.
 */
void set_player_name(const char *player_name)
{
	if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "radiobutton1"))))	
		{
		 GtkLabel *g1 =GTK_LABEL(gtk_builder_get_object(builder,"label52"));
		 gtk_label_set_text(g1, player_name);	
		 P1=player_name;
		}
	else 
		{
	     GtkLabel *g2 =GTK_LABEL(gtk_builder_get_object(builder,"label53"));
		 gtk_label_set_text(g2, player_name);
	 	 P2=player_name;
	    }	

	const char str3[]="Nome modificato ", *p3=str3;
	GtkLabel *name_label =GTK_LABEL(gtk_builder_get_object(builder,"label72"));
	gtk_label_set_text(name_label, p3);

	GtkWidget *mod_dialog =GTK_WIDGET(gtk_builder_get_object(builder,"dialog10"));
	gtk_widget_show_all(mod_dialog); 
}

/**
 * Funzione che acquisisce i nomi dei giocatori inseriti dall'utente nell'apposita finestra. 
 * Una volta fatto ciò, viene chiamata la funzione ::set_player_name a cui viene passato
 * il puntatore costante alla stringa contenente il nome del giocatore appena inserito.
 * Il tutto avviene quando si preme il bottone 'Fatto' della suddetta finestra.
 */
extern "C" void get_name(GtkWidget *widget, gpointer user_data)
{
	GtkTextView *insert_box=GTK_TEXT_VIEW(gtk_builder_get_object(builder, "textview1"));
    GtkTextBuffer *buf= gtk_text_view_get_buffer(insert_box);

	GtkTextIter start, end;
	gtk_text_buffer_get_bounds(buf, &start, &end);
	const char *player_name= gtk_text_buffer_get_text(buf, &start, &end, TRUE) ;

	set_player_name(player_name);
}

/**
 * Questa funzione resetta i punteggi delle partite vinte da entrambi i giocatori.
 * Vengono settate a zero le due variabili globali che contengono i valori attuali 
 * delle vittorie e poi viene chiamata due volte la funzione ::points_updater
 * (una volta per resettare i punteggi del g1 e una volta per il g2).
 * Fatto ciò viene mostrata la finestra che conferma il reset dei punteggi.
 */
extern "C" void reset_event(GtkWidget *widget, gpointer user_data)
{	
	giocatori tmp=gamer;
	r_m_won=0, y_m_won=0;
	gamer=player1; points_updater();
	gamer=player2; points_updater();
	gamer=tmp;

	const char str5[]="Punteggi resettati ", *p5=str5;
	GtkLabel *points_label =GTK_LABEL(gtk_builder_get_object(builder,"label72"));
	gtk_label_set_text(points_label, p5);

	GtkWidget *mod_dialog =GTK_WIDGET(gtk_builder_get_object(builder,"dialog10"));
	gtk_widget_show_all(mod_dialog); 
}

